<template>
  <div class="dict-management">
    <el-row :gutter="20">
      <!-- 字典类型列表 -->
      <el-col :span="8" :xs="24">
        <el-card class="dict-type-card">
          <template #header>
            <div class="card-header">
              <span>字典类型</span>
              <el-button
                v-permission="['system:dict:add']"
                type="primary"
                size="small"
                icon="Plus"
                @click="handleAddType"
              >
                新增
              </el-button>
            </div>
          </template>

          <!-- 字典类型搜索 -->
          <el-form :model="typeQueryForm" :inline="true" label-width="80px">
            <el-form-item label="字典名称" prop="dictName">
              <el-input
                v-model="typeQueryForm.dictName"
                placeholder="请输入字典名称"
                clearable
                size="small"
                @keyup.enter="getTypeList"
              />
            </el-form-item>
            <el-form-item label="字典类型" prop="dictType">
              <el-input
                v-model="typeQueryForm.dictType"
                placeholder="请输入字典类型"
                clearable
                size="small"
                @keyup.enter="getTypeList"
              />
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-select
                v-model="typeQueryForm.status"
                placeholder="字典状态"
                clearable
                size="small"
              >
                <el-option label="正常" value="0" />
                <el-option label="停用" value="1" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" size="small" @click="getTypeList">
                搜索
              </el-button>
              <el-button icon="Refresh" size="small" @click="resetTypeQuery">
                重置
              </el-button>
            </el-form-item>
          </el-form>

          <!-- 字典类型表格 -->
          <el-table
            v-loading="typeLoading"
            :data="typeList"
            @row-click="clickRow"
            highlight-current-row
            style="width: 100%"
          >
            <el-table-column prop="dictName" label="字典名称" show-overflow-tooltip />
            <el-table-column prop="dictType" label="字典类型" show-overflow-tooltip />
            <el-table-column prop="status" label="状态" width="80">
              <template #default="{ row }">
                <dict-tag :options="statusOptions" :value="row.status" />
              </template>
            </el-table-column>
            <el-table-column label="操作" width="160" class-name="small-padding fixed-width">
              <template #default="{ row }">
                <el-tooltip content="修改" placement="top">
                  <el-button
                    v-permission="['system:dict:edit']"
                    link
                    type="primary"
                    icon="Edit"
                    @click.stop="handleUpdateType(row)"
                  />
                </el-tooltip>
                <el-tooltip content="删除" placement="top">
                  <el-button
                    v-permission="['system:dict:remove']"
                    link
                    type="danger"
                    icon="Delete"
                    @click.stop="handleDeleteType(row)"
                  />
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>

          <!-- 分页 -->
          <pagination
            v-show="typeTotal > 0"
            v-model:page="typeQueryForm.pageNum"
            v-model:limit="typeQueryForm.pageSize"
            :total="typeTotal"
            :page-sizes="[10, 20, 30, 50]"
            :layout="'total, sizes, prev, pager, next, jumper'"
            @pagination="getTypeList"
          />
        </el-card>
      </el-col>

      <!-- 字典数据列表 -->
      <el-col :span="16" :xs="24">
        <el-card class="dict-data-card">
          <template #header>
            <div class="card-header">
              <span v-if="currentType.dictId">{{ currentType.dictName }}（{{ currentType.dictType }}）</span>
              <span v-else>请选择字典类型</span>
              <div v-if="currentType.dictId">
                <el-button
                  v-permission="['system:dict:add']"
                  type="primary"
                  size="small"
                  icon="Plus"
                  @click="handleAddData"
                >
                  新增
                </el-button>
                <el-button
                  v-permission="['system:dict:export']"
                  type="success"
                  size="small"
                  icon="Download"
                  @click="handleExportData"
                >
                  导出
                </el-button>
              </div>
            </div>
          </template>

          <div v-if="currentType.dictId">
            <!-- 字典数据搜索 -->
            <el-form :model="dataQueryForm" :inline="true" label-width="80px">
              <el-form-item label="字典标签" prop="dictLabel">
                <el-input
                  v-model="dataQueryForm.dictLabel"
                  placeholder="请输入字典标签"
                  clearable
                  size="small"
                  @keyup.enter="getDataList"
                />
              </el-form-item>
              <el-form-item label="状态" prop="status">
                <el-select
                  v-model="dataQueryForm.status"
                  placeholder="数据状态"
                  clearable
                  size="small"
                >
                  <el-option label="正常" value="0" />
                  <el-option label="停用" value="1" />
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon="Search" size="small" @click="getDataList">
                  搜索
                </el-button>
                <el-button icon="Refresh" size="small" @click="resetDataQuery">
                  重置
                </el-button>
              </el-form-item>
            </el-form>

            <!-- 字典数据表格 -->
            <el-table v-loading="dataLoading" :data="dataList">
              <el-table-column prop="dictSort" label="字典排序" width="100" />
              <el-table-column prop="dictLabel" label="字典标签" show-overflow-tooltip />
              <el-table-column prop="dictValue" label="字典键值" show-overflow-tooltip />
              <el-table-column prop="dictType" label="字典类型" show-overflow-tooltip />
              <el-table-column prop="cssClass" label="样式属性" show-overflow-tooltip />
              <el-table-column prop="listClass" label="表格字典样式" show-overflow-tooltip />
              <el-table-column prop="isDefault" label="是否默认" width="100">
                <template #default="{ row }">
                  <dict-tag :options="yesNoOptions" :value="row.isDefault" />
                </template>
              </el-table-column>
              <el-table-column prop="status" label="状态" width="80">
                <template #default="{ row }">
                  <dict-tag :options="statusOptions" :value="row.status" />
                </template>
              </el-table-column>
              <el-table-column
                label="创建时间"
                prop="createTime"
                width="160"
              >
                <template #default="{ row }">
                  <span>{{ parseTime(row.createTime) }}</span>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="160" class-name="small-padding fixed-width">
                <template #default="{ row }">
                  <el-tooltip content="修改" placement="top">
                    <el-button
                      v-permission="['system:dict:edit']"
                      link
                      type="primary"
                      icon="Edit"
                      @click="handleUpdateData(row)"
                    />
                  </el-tooltip>
                  <el-tooltip content="删除" placement="top">
                    <el-button
                      v-permission="['system:dict:remove']"
                      link
                      type="danger"
                      icon="Delete"
                      @click="handleDeleteData(row)"
                    />
                  </el-tooltip>
                </template>
              </el-table-column>
            </el-table>

            <!-- 分页 -->
            <pagination
              v-show="dataTotal > 0"
              v-model:page="dataQueryForm.pageNum"
              v-model:limit="dataQueryForm.pageSize"
              :total="dataTotal"
              @pagination="getDataList"
            />
          </div>
          <div v-else class="no-data">
            <el-empty description="请选择字典类型查看数据" />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 添加或修改字典类型对话框 -->
    <el-dialog v-model="typeDialogVisible" :title="typeDialogTitle" width="500px" :before-close="cancelType">
      <el-form ref="typeFormRef" :model="typeForm" :rules="typeFormRules" label-width="80px">
        <el-form-item label="字典名称" prop="dictName">
          <el-input v-model="typeForm.dictName" placeholder="请输入字典名称" />
        </el-form-item>
        <el-form-item label="字典类型" prop="dictType">
          <el-input v-model="typeForm.dictType" placeholder="请输入字典类型" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="typeForm.status">
            <el-radio label="0">正常</el-radio>
            <el-radio label="1">停用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="typeForm.remark"
            type="textarea"
            placeholder="请输入内容"
            :rows="3"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitTypeForm">确 定</el-button>
          <el-button @click="cancelType">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 添加或修改字典数据对话框 -->
    <el-dialog v-model="dataDialogVisible" :title="dataDialogTitle" width="500px" :before-close="cancelData">
      <el-form ref="dataFormRef" :model="dataForm" :rules="dataFormRules" label-width="80px">
        <el-form-item label="字典类型">
          <el-input v-model="dataForm.dictType" :disabled="true" />
        </el-form-item>
        <el-form-item label="数据标签" prop="dictLabel">
          <el-input v-model="dataForm.dictLabel" placeholder="请输入数据标签" />
        </el-form-item>
        <el-form-item label="数据键值" prop="dictValue">
          <el-input v-model="dataForm.dictValue" placeholder="请输入数据键值" />
        </el-form-item>
        <el-form-item label="样式属性" prop="cssClass">
          <el-input v-model="dataForm.cssClass" placeholder="请输入样式属性" />
        </el-form-item>
        <el-form-item label="显示排序" prop="dictSort">
          <el-input-number v-model="dataForm.dictSort" controls-position="right" :min="0" />
        </el-form-item>
        <el-form-item label="回显样式" prop="listClass">
          <el-select v-model="dataForm.listClass" placeholder="请选择">
            <el-option label="默认" value="default" />
            <el-option label="主要" value="primary" />
            <el-option label="成功" value="success" />
            <el-option label="信息" value="info" />
            <el-option label="警告" value="warning" />
            <el-option label="危险" value="danger" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="dataForm.status">
            <el-radio label="0">正常</el-radio>
            <el-radio label="1">停用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="是否默认" prop="isDefault">
          <el-radio-group v-model="dataForm.isDefault">
            <el-radio label="Y">是</el-radio>
            <el-radio label="N">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="dataForm.remark"
            type="textarea"
            placeholder="请输入内容"
            :rows="3"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitDataForm">确 定</el-button>
          <el-button @click="cancelData">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import {
  getDictTypeList,
  getDictType,
  addDictType,
  updateDictType,
  delDictType,
  exportDictType,
  refreshCache,
} from '@/api/system/dictType'
import {
  getDictDataList,
  getDictData,
  addDictData,
  updateDictData,
  delDictData,
  exportDictData,
} from '@/api/system/dictData'
import { parseTime } from '@/utils/global'
import DictTag from '@/components/DictTag/index.vue'
import Pagination from '@/components/Pagination/index.vue'

// 字典类型相关
const typeLoading = ref(true)
const typeList = ref<any[]>([])
const typeTotal = ref(0)
const typeDialogVisible = ref(false)
const typeDialogTitle = ref('')
const currentType = ref<any>({})
const typeFormRef = ref<FormInstance>()

// 字典数据相关
const dataLoading = ref(false)
const dataList = ref<any[]>([])
const dataTotal = ref(0)
const dataDialogVisible = ref(false)
const dataDialogTitle = ref('')
const dataFormRef = ref<FormInstance>()

// 状态数据字典
const statusOptions = ref([
  { label: '正常', value: '0', elTagType: 'primary' },
  { label: '停用', value: '1', elTagType: 'danger' },
])

// 是否默认数据字典
const yesNoOptions = ref([
  { label: '是', value: 'Y', elTagType: 'success' },
  { label: '否', value: 'N', elTagType: 'info' },
])

// 字典类型查询参数
const typeQueryForm = reactive({
  pageNum: 1,
  pageSize: 10,
  dictName: '',
  dictType: '',
  status: '',
})

// 字典数据查询参数
const dataQueryForm = reactive({
  pageNum: 1,
  pageSize: 10,
  dictType: '',
  dictLabel: '',
  status: '',
})

// 字典类型表单数据
const typeForm = reactive({
  dictId: undefined,
  dictName: '',
  dictType: '',
  status: '0',
  remark: '',
})

// 字典数据表单数据
const dataForm = reactive({
  dictCode: undefined,
  dictSort: 0,
  dictLabel: '',
  dictValue: '',
  dictType: '',
  cssClass: '',
  listClass: '',
  isDefault: 'N',
  status: '0',
  remark: '',
})

// 字典类型表单校验
const typeFormRules: FormRules = {
  dictName: [
    { required: true, message: '字典名称不能为空', trigger: 'blur' },
  ],
  dictType: [
    { required: true, message: '字典类型不能为空', trigger: 'blur' },
  ],
}

// 字典数据表单校验
const dataFormRules: FormRules = {
  dictLabel: [
    { required: true, message: '数据标签不能为空', trigger: 'blur' },
  ],
  dictValue: [
    { required: true, message: '数据键值不能为空', trigger: 'blur' },
  ],
  dictSort: [
    { required: true, message: '数据顺序不能为空', trigger: 'blur' },
  ],
}

/** 查询字典类型列表 */
const getTypeList = async () => {
  typeLoading.value = true
  try {
    const { data } = await getDictTypeList(typeQueryForm)
    typeList.value = data.rows
    typeTotal.value = data.total
  } catch (error) {
    console.error('获取字典类型列表失败:', error)
  } finally {
    typeLoading.value = false
  }
}

/** 查询字典数据列表 */
const getDataList = async () => {
  if (!currentType.value.dictType) return

  dataLoading.value = true
  try {
    dataQueryForm.dictType = currentType.value.dictType
    const { data } = await getDictDataList(dataQueryForm)
    dataList.value = data.rows
    dataTotal.value = data.total
  } catch (error) {
    console.error('获取字典数据列表失败:', error)
  } finally {
    dataLoading.value = false
  }
}

/** 点击字典类型行 */
const clickRow = (row: any) => {
  currentType.value = row
  dataQueryForm.dictType = row.dictType
  resetDataQuery()
  getDataList()
}

/** 重置字典类型查询 */
const resetTypeQuery = () => {
  Object.assign(typeQueryForm, {
    pageNum: 1,
    pageSize: 10,
    dictName: '',
    dictType: '',
    status: '',
  })
  getTypeList()
}

/** 重置字典数据查询 */
const resetDataQuery = () => {
  Object.assign(dataQueryForm, {
    pageNum: 1,
    pageSize: 10,
    dictType: currentType.value.dictType || '',
    dictLabel: '',
    status: '',
  })
  getDataList()
}

/** 新增字典类型按钮操作 */
const handleAddType = () => {
  resetTypeForm()
  typeDialogVisible.value = true
  typeDialogTitle.value = '添加字典类型'
}

/** 修改字典类型按钮操作 */
const handleUpdateType = async (row: any) => {
  resetTypeForm()
  try {
    const { data } = await getDictType(row.dictId)
    Object.assign(typeForm, data)
    typeDialogVisible.value = true
    typeDialogTitle.value = '修改字典类型'
  } catch (error) {
    console.error('获取字典类型信息失败:', error)
  }
}

/** 删除字典类型按钮操作 */
const handleDeleteType = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `是否确认删除字典编号为"${row.dictId}"的数据项？`,
      '警告',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    await delDictType(row.dictId)
    await getTypeList()
    ElMessage.success('删除成功')
  } catch (error) {
    console.log('取消删除')
  }
}

/** 新增字典数据按钮操作 */
const handleAddData = () => {
  resetDataForm()
  dataForm.dictType = currentType.value.dictType
  dataDialogVisible.value = true
  dataDialogTitle.value = '添加字典数据'
}

/** 修改字典数据按钮操作 */
const handleUpdateData = async (row: any) => {
  resetDataForm()
  try {
    const { data } = await getDictData(row.dictCode)
    Object.assign(dataForm, data)
    dataDialogVisible.value = true
    dataDialogTitle.value = '修改字典数据'
  } catch (error) {
    console.error('获取字典数据信息失败:', error)
  }
}

/** 删除字典数据按钮操作 */
const handleDeleteData = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `是否确认删除字典编号为"${row.dictCode}"的数据项？`,
      '警告',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    await delDictData(row.dictCode)
    await getDataList()
    ElMessage.success('删除成功')
  } catch (error) {
    console.log('取消删除')
  }
}

/** 导出字典数据按钮操作 */
const handleExportData = async () => {
  try {
    await ElMessageBox.confirm('是否确认导出所有字典数据项？', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })

    await exportDictData(dataQueryForm)
  } catch (error) {
    console.log('取消导出')
  }
}

/** 提交字典类型表单 */
const submitTypeForm = () => {
  typeFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      try {
        if (typeForm.dictId !== undefined) {
          await updateDictType(typeForm)
        } else {
          await addDictType(typeForm)
        }
        typeDialogVisible.value = false
        await getTypeList()
      } catch (error) {
        console.error('提交字典类型失败:', error)
      }
    }
  })
}

/** 提交字典数据表单 */
const submitDataForm = () => {
  dataFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      try {
        if (dataForm.dictCode !== undefined) {
          await updateDictData(dataForm)
        } else {
          await addDictData(dataForm)
        }
        dataDialogVisible.value = false
        await getDataList()
      } catch (error) {
        console.error('提交字典数据失败:', error)
      }
    }
  })
}

/** 取消字典类型按钮 */
const cancelType = () => {
  typeDialogVisible.value = false
  resetTypeForm()
}

/** 取消字典数据按钮 */
const cancelData = () => {
  dataDialogVisible.value = false
  resetDataForm()
}

/** 重置字典类型表单 */
const resetTypeForm = () => {
  Object.assign(typeForm, {
    dictId: undefined,
    dictName: '',
    dictType: '',
    status: '0',
    remark: '',
  })
  typeFormRef.value?.resetFields()
}

/** 重置字典数据表单 */
const resetDataForm = () => {
  Object.assign(dataForm, {
    dictCode: undefined,
    dictSort: 0,
    dictLabel: '',
    dictValue: '',
    dictType: '',
    cssClass: '',
    listClass: '',
    isDefault: 'N',
    status: '0',
    remark: '',
  })
  dataFormRef.value?.resetFields()
}

// 初始化
onMounted(() => {
  getTypeList()
})
</script>

<style lang="scss" scoped>
.dict-management {
  padding: 20px;
}

.dict-type-card,
.dict-data-card {
  height: calc(100vh - 120px);
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}

.no-data {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300px;
}

:deep(.el-table) {
  .el-table__cell {
    padding: 8px 0;
  }
}

.dialog-footer {
  text-align: center;
}

// 移动端适配
@media (max-width: 768px) {
  .dict-type-card,
  .dict-data-card {
    height: auto;
    margin-bottom: 20px;
  }
}
</style>

